package controller

import (
	"a-common/constant"
	"a-common/myerr"
	"a-system/domain/entity"
	"a-system/service"
	"fmt"
	"strconv"
	"sync"

	"github.com/gofiber/fiber/v2"
)

var (
	roleControllerTemp *RoleController
	sysRoleService     = service.NewSysRoleService()
	roleControllerOnce sync.Once
)

type RoleController struct{}

func NewSysRoleController() *RoleController {
	roleControllerOnce.Do(func() {
		roleControllerTemp = &RoleController{}
	})
	return roleControllerTemp
}

// List 列表
func (m *RoleController) List(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.QueryParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	err := args.Validator()
	if err != nil {
		return err
	}

	// 查询
	vPage, err := sysRoleService.List(&args)
	if err != nil {
		return err
	}
	return Resp(c, vPage)
}

// Get 查
func (m *RoleController) Get(c *fiber.Ctx) error {
	id := c.Params("id")
	if id == "" {
		return myerr.ERR_SYS_ARGS
	}
	data, err := sysRoleService.Get(id)
	if err != nil {
		return err
	}
	return Resp(c, data)
}

// Del 删
func (m *RoleController) Del(c *fiber.Ctx) error {
	ids := c.Params("ids")
	if ids == "" {
		return myerr.ERR_SYS_ARGS
	}
	err := sysRoleService.Del(ids)
	if err != nil {
		return err
	}
	return Ok(c)
}

// Add 增
func (m *RoleController) Add(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	user := GetUser(c)
	args.CreatedBy = user.Account

	err := sysRoleService.Add(&args)
	if err != nil {
		return err
	}
	return Ok(c)
}

// Edit 改
func (m *RoleController) Edit(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	user := GetUser(c)
	args.UpdatedBy = user.Account

	// 校验角色是否允许操作
	if args.RoleId == constant.ADMIN_ID {
		return myerr.ERR_SYS_403
	}
	// 校验角色是否有数据权限
	if user.Uid != constant.ADMIN_ID {
		if v, err := sysRoleService.Get(strconv.FormatInt(args.RoleId, 10)); v.RoleId == 0 || err != nil {
			return myerr.ERR_SYS_403
		}
	}

	// 更新角色信息
	err := sysRoleService.Edit(&args)
	if err != nil {
		return err
	}
	return Ok(c)
}

// Export 导出
func (m *RoleController) Export(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.QueryParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}

	f, err := sysRoleService.Export(&args)
	if err != nil {
		return err
	}

	c.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, "角色表.xlsx"))
	if err := f.Write(c.Response().BodyWriter()); err != nil {
		return err
	}
	return nil
}

// ChangeStatus 切换状态
func (m *RoleController) ChangeStatus(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	if args.RoleId == 0 || args.Status == "" {
		return myerr.ERR_SYS_ARGS
	}
	_, err := sysRoleService.ChangeStatus(&args)
	if err != nil {
		return err
	}
	return Ok(c)
}

// DataScope 修改保存数据权限
func (m *RoleController) DataScope(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	if args.RoleId == 0 || args.Status == "" {
		return myerr.ERR_SYS_ARGS
	}
	// 校验角色是否允许操作
	if args.RoleId == constant.ADMIN_ID {
		return myerr.ERR_SYS_403
	}
	user := GetUser(c)
	args.UpdatedBy = user.Account

	err := sysRoleService.DataScope(&args, user.Uid)
	if err != nil {
		return err
	}
	return Ok(c)
}

// DeptTree 部门树
func (m *RoleController) DeptTree(c *fiber.Ctx) error {
	roleId := c.Params("id")
	if roleId == "" {
		return myerr.ERR_SYS_ARGS
	}
	data, err := sysRoleService.DeptTree(roleId)
	if err != nil {
		return err
	}
	return Resp(c, data)
}

// EditAndMenu
func (m *RoleController) EditAndMenu(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	user := GetUser(c)
	args.UpdatedBy = user.Account

	err := sysRoleService.Edit(&args)
	if err != nil {
		return err
	}
	return Ok(c)
}

func (m *RoleController) EditAndDept(c *fiber.Ctx) error {
	var args entity.SysRoleDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	user := GetUser(c)
	args.UpdatedBy = user.Account

	// 更新角色权限部门
	err := sysRoleService.EditAndDept(&args)
	if err != nil {
		return err
	}
	return Ok(c)
}

// SelectAll 批量选择用户授权
func (m *RoleController) SelectAll(c *fiber.Ctx) error {
	roleId := c.Query("roleId")
	userIds := c.Query("userIds")
	user := GetUser(c)

	// 校验角色是否有数据权限
	if user.Uid != constant.ADMIN_ID {
		if v, err := sysRoleService.Get(roleId); v.RoleId == 0 || err != nil {
			return myerr.ERR_SYS_403
		}
	}

	err := sysRoleService.SelectAll(roleId, userIds, user.Uid)
	if err != nil {
		return err
	}
	return Ok(c)
}

// Cancel 取消授权用户
func (m *RoleController) Cancel(c *fiber.Ctx) error {
	var args entity.SysUserRole
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	if args.RoleId == 0 || args.UserId == 0 {
		return myerr.ERR_SYS_ARGS
	}
	if _, err := sysRoleService.Cancel(&args); err != nil {
		return err
	}

	return Ok(c)
}

// CancelAll 批量取消授权用户
func (m *RoleController) CancelAll(c *fiber.Ctx) error {
	roleId := c.Query("roleId")
	userIds := c.Query("userIds")
	if roleId == "" || userIds == "" {
		return myerr.ERR_SYS_ARGS
	}

	if _, err := sysRoleService.CancelAll(roleId, userIds); err != nil {
		return err
	}
	return Ok(c)
}
